; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -passes=instsimplify -S < %s | FileCheck %s
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

@g1 = global i32 0, align 4
@g2 = internal global i32 0, align 4
@g3 = unnamed_addr global i32 0, align 4
@g4 = hidden global i32 0, align 4
@g5 = protected global i32 0, align 4
@g6 = thread_local unnamed_addr global i32 0, align 4

; Make sure we can simplify away a pointer comparison between
; dynamically-allocated memory and a local stack allocation.
;   void p()
;   {
;     int *mData;
;     int mStackData[10];
;     mData = new int[12];
;     if (mData != mStackData) {
;       delete[] mData;
;     }
;   }

define void @_Z2p1v() {
; CHECK-LABEL: @_Z2p1v(
; CHECK-NEXT:  bb:
; CHECK-NEXT:    [[I1:%.*]] = tail call noalias ptr @_Znam(i64 48) #[[ATTR2:[0-9]+]]
; CHECK-NEXT:    br i1 false, label [[BB6:%.*]], label [[BB5:%.*]]
; CHECK:       bb5:
; CHECK-NEXT:    call void @_ZdaPv(ptr [[I1]]) #[[ATTR3:[0-9]+]]
; CHECK-NEXT:    br label [[BB6]]
; CHECK:       bb6:
; CHECK-NEXT:    ret void
;
bb:
  %mStackData = alloca [10 x i32], align 16
  %i1 = tail call noalias ptr @_Znam(i64 48) #3
  %i4 = icmp eq ptr %i1, %mStackData
  br i1 %i4, label %bb6, label %bb5

bb5:                                              ; preds = %bb
  call void @_ZdaPv(ptr %i1) #4
  br label %bb6

bb6:                                              ; preds = %bb5, %bb
  ret void
}

define void @_Z2p2bb(i1 zeroext %b1, i1 zeroext %b2) {
; CHECK-LABEL: @_Z2p2bb(
; CHECK-NEXT:  bb:
; CHECK-NEXT:    [[I3:%.*]] = tail call noalias ptr @_Znam(i64 48) #[[ATTR2]]
; CHECK-NEXT:    [[I4:%.*]] = tail call noalias ptr @_Znam(i64 48) #[[ATTR2]]
; CHECK-NEXT:    br i1 false, label [[BB8:%.*]], label [[BB7:%.*]]
; CHECK:       bb7:
; CHECK-NEXT:    call void @_ZdaPv(ptr [[I3]]) #[[ATTR3]]
; CHECK-NEXT:    call void @_ZdaPv(ptr [[I4]]) #[[ATTR3]]
; CHECK-NEXT:    br label [[BB8]]
; CHECK:       bb8:
; CHECK-NEXT:    ret void
;
bb:
  %mStackData = alloca [10 x i32], align 16
  %i2 = select i1 %b1, ptr %mStackData, ptr @g2
  %i3 = tail call noalias ptr @_Znam(i64 48) #3
  %i4 = tail call noalias ptr @_Znam(i64 48) #3
  %.v = select i1 %b2, ptr %i3, ptr %i4
  %i6 = icmp eq ptr %.v, %i2
  br i1 %i6, label %bb8, label %bb7

bb7:                                              ; preds = %bb
  call void @_ZdaPv(ptr %i3) #4
  call void @_ZdaPv(ptr %i4) #4
  br label %bb8

bb8:                                              ; preds = %bb7, %bb
  ret void
}

define void @_Z2p4bb(i1 zeroext %b1, i1 zeroext %b2) {
; CHECK-LABEL: @_Z2p4bb(
; CHECK-NEXT:  bb:
; CHECK-NEXT:    [[I3:%.*]] = tail call noalias ptr @_Znam(i64 48) #[[ATTR2]]
; CHECK-NEXT:    [[I4:%.*]] = tail call noalias ptr @_Znam(i64 48) #[[ATTR2]]
; CHECK-NEXT:    br i1 false, label [[BB8:%.*]], label [[BB7:%.*]]
; CHECK:       bb7:
; CHECK-NEXT:    call void @_ZdaPv(ptr [[I3]]) #[[ATTR3]]
; CHECK-NEXT:    call void @_ZdaPv(ptr [[I4]]) #[[ATTR3]]
; CHECK-NEXT:    br label [[BB8]]
; CHECK:       bb8:
; CHECK-NEXT:    ret void
;
bb:
  %mStackData = alloca [10 x i32], align 16
  %i2 = select i1 %b1, ptr %mStackData, ptr @g3
  %i3 = tail call noalias ptr @_Znam(i64 48) #3
  %i4 = tail call noalias ptr @_Znam(i64 48) #3
  %.v = select i1 %b2, ptr %i3, ptr %i4
  %i6 = icmp eq ptr %.v, %i2
  br i1 %i6, label %bb8, label %bb7

bb7:                                              ; preds = %bb
  call void @_ZdaPv(ptr %i3) #4
  call void @_ZdaPv(ptr %i4) #4
  br label %bb8

bb8:                                              ; preds = %bb7, %bb
  ret void
}

define void @_Z2p5bb(i1 zeroext %b1, i1 zeroext %b2) {
; CHECK-LABEL: @_Z2p5bb(
; CHECK-NEXT:  bb:
; CHECK-NEXT:    [[I3:%.*]] = tail call noalias ptr @_Znam(i64 48) #[[ATTR2]]
; CHECK-NEXT:    [[I4:%.*]] = tail call noalias ptr @_Znam(i64 48) #[[ATTR2]]
; CHECK-NEXT:    br i1 false, label [[BB8:%.*]], label [[BB7:%.*]]
; CHECK:       bb7:
; CHECK-NEXT:    call void @_ZdaPv(ptr [[I3]]) #[[ATTR3]]
; CHECK-NEXT:    call void @_ZdaPv(ptr [[I4]]) #[[ATTR3]]
; CHECK-NEXT:    br label [[BB8]]
; CHECK:       bb8:
; CHECK-NEXT:    ret void
;
bb:
  %mStackData = alloca [10 x i32], align 16
  %i2 = select i1 %b1, ptr %mStackData, ptr @g4
  %i3 = tail call noalias ptr @_Znam(i64 48) #3
  %i4 = tail call noalias ptr @_Znam(i64 48) #3
  %.v = select i1 %b2, ptr %i3, ptr %i4
  %i6 = icmp eq ptr %.v, %i2
  br i1 %i6, label %bb8, label %bb7

bb7:                                              ; preds = %bb
  call void @_ZdaPv(ptr %i3) #4
  call void @_ZdaPv(ptr %i4) #4
  br label %bb8

bb8:                                              ; preds = %bb7, %bb
  ret void
}

define void @_Z2p6bb(i1 zeroext %b1, i1 zeroext %b2) {
; CHECK-LABEL: @_Z2p6bb(
; CHECK-NEXT:  bb:
; CHECK-NEXT:    [[I3:%.*]] = tail call noalias ptr @_Znam(i64 48) #[[ATTR2]]
; CHECK-NEXT:    [[I4:%.*]] = tail call noalias ptr @_Znam(i64 48) #[[ATTR2]]
; CHECK-NEXT:    br i1 false, label [[BB8:%.*]], label [[BB7:%.*]]
; CHECK:       bb7:
; CHECK-NEXT:    call void @_ZdaPv(ptr [[I3]]) #[[ATTR3]]
; CHECK-NEXT:    call void @_ZdaPv(ptr [[I4]]) #[[ATTR3]]
; CHECK-NEXT:    br label [[BB8]]
; CHECK:       bb8:
; CHECK-NEXT:    ret void
;
bb:
  %mStackData = alloca [10 x i32], align 16
  %i2 = select i1 %b1, ptr %mStackData, ptr @g5
  %i3 = tail call noalias ptr @_Znam(i64 48) #3
  %i4 = tail call noalias ptr @_Znam(i64 48) #3
  %.v = select i1 %b2, ptr %i3, ptr %i4
  %i6 = icmp eq ptr %.v, %i2
  br i1 %i6, label %bb8, label %bb7

bb7:                                              ; preds = %bb
  call void @_ZdaPv(ptr %i3) #4
  call void @_ZdaPv(ptr %i4) #4
  br label %bb8

bb8:                                              ; preds = %bb7, %bb
  ret void
}

define void @_Z4nopebbPi(i1 zeroext %b1, i1 zeroext %b2, ptr readnone %q) {
; CHECK-LABEL: @_Z4nopebbPi(
; CHECK-NEXT:  bb:
; CHECK-NEXT:    [[MSTACKDATA:%.*]] = alloca [10 x i32], align 16
; CHECK-NEXT:    [[I2:%.*]] = select i1 [[B1:%.*]], ptr [[MSTACKDATA]], ptr [[Q:%.*]]
; CHECK-NEXT:    [[I3:%.*]] = tail call noalias ptr @_Znam(i64 48) #[[ATTR2]]
; CHECK-NEXT:    [[I4:%.*]] = tail call noalias ptr @_Znam(i64 48) #[[ATTR2]]
; CHECK-NEXT:    [[DOTV:%.*]] = select i1 [[B2:%.*]], ptr [[I3]], ptr [[I4]]
; CHECK-NEXT:    [[I6:%.*]] = icmp eq ptr [[DOTV]], [[I2]]
; CHECK-NEXT:    br i1 [[I6]], label [[BB8:%.*]], label [[BB7:%.*]]
; CHECK:       bb7:
; CHECK-NEXT:    call void @_ZdaPv(ptr [[I3]]) #[[ATTR3]]
; CHECK-NEXT:    call void @_ZdaPv(ptr [[I4]]) #[[ATTR3]]
; CHECK-NEXT:    br label [[BB8]]
; CHECK:       bb8:
; CHECK-NEXT:    ret void
;
bb:
  %mStackData = alloca [10 x i32], align 16
  %i2 = select i1 %b1, ptr %mStackData, ptr %q
  %i3 = tail call noalias ptr @_Znam(i64 48) #3
  %i4 = tail call noalias ptr @_Znam(i64 48) #3
  %.v = select i1 %b2, ptr %i3, ptr %i4
  %i6 = icmp eq ptr %.v, %i2
  br i1 %i6, label %bb8, label %bb7

bb7:                                              ; preds = %bb
  call void @_ZdaPv(ptr %i3) #4
  call void @_ZdaPv(ptr %i4) #4
  br label %bb8

bb8:                                              ; preds = %bb7, %bb
  ret void
}

define void @_Z2p3bb(i1 zeroext %b1, i1 zeroext %b2) {
; CHECK-LABEL: @_Z2p3bb(
; CHECK-NEXT:  bb:
; CHECK-NEXT:    [[MSTACKDATA:%.*]] = alloca [10 x i32], align 16
; CHECK-NEXT:    [[I2:%.*]] = select i1 [[B1:%.*]], ptr [[MSTACKDATA]], ptr @g1
; CHECK-NEXT:    [[I3:%.*]] = tail call noalias ptr @_Znam(i64 48) #[[ATTR2]]
; CHECK-NEXT:    [[I4:%.*]] = tail call noalias ptr @_Znam(i64 48) #[[ATTR2]]
; CHECK-NEXT:    [[DOTV:%.*]] = select i1 [[B2:%.*]], ptr [[I3]], ptr [[I4]]
; CHECK-NEXT:    [[I6:%.*]] = icmp eq ptr [[DOTV]], [[I2]]
; CHECK-NEXT:    br i1 [[I6]], label [[BB8:%.*]], label [[BB7:%.*]]
; CHECK:       bb7:
; CHECK-NEXT:    call void @_ZdaPv(ptr [[I3]]) #[[ATTR3]]
; CHECK-NEXT:    call void @_ZdaPv(ptr [[I4]]) #[[ATTR3]]
; CHECK-NEXT:    br label [[BB8]]
; CHECK:       bb8:
; CHECK-NEXT:    ret void
;
bb:
  %mStackData = alloca [10 x i32], align 16
  %i2 = select i1 %b1, ptr %mStackData, ptr @g1
  %i3 = tail call noalias ptr @_Znam(i64 48) #3
  %i4 = tail call noalias ptr @_Znam(i64 48) #3
  %.v = select i1 %b2, ptr %i3, ptr %i4
  %i6 = icmp eq ptr %.v, %i2
  br i1 %i6, label %bb8, label %bb7

bb7:                                              ; preds = %bb
  call void @_ZdaPv(ptr %i3) #4
  call void @_ZdaPv(ptr %i4) #4
  br label %bb8

bb8:                                              ; preds = %bb7, %bb
  ret void
}

define void @_Z2p7bb(i1 zeroext %b1, i1 zeroext %b2) {
; CHECK-LABEL: @_Z2p7bb(
; CHECK-NEXT:  bb:
; CHECK-NEXT:    [[MSTACKDATA:%.*]] = alloca [10 x i32], align 16
; CHECK-NEXT:    [[I2:%.*]] = select i1 [[B1:%.*]], ptr [[MSTACKDATA]], ptr @g6
; CHECK-NEXT:    [[I3:%.*]] = tail call noalias ptr @_Znam(i64 48) #[[ATTR2]]
; CHECK-NEXT:    [[I4:%.*]] = tail call noalias ptr @_Znam(i64 48) #[[ATTR2]]
; CHECK-NEXT:    [[DOTV:%.*]] = select i1 [[B2:%.*]], ptr [[I3]], ptr [[I4]]
; CHECK-NEXT:    [[I6:%.*]] = icmp eq ptr [[DOTV]], [[I2]]
; CHECK-NEXT:    br i1 [[I6]], label [[BB8:%.*]], label [[BB7:%.*]]
; CHECK:       bb7:
; CHECK-NEXT:    call void @_ZdaPv(ptr [[I3]]) #[[ATTR3]]
; CHECK-NEXT:    call void @_ZdaPv(ptr [[I4]]) #[[ATTR3]]
; CHECK-NEXT:    br label [[BB8]]
; CHECK:       bb8:
; CHECK-NEXT:    ret void
;
bb:
  %mStackData = alloca [10 x i32], align 16
  %i2 = select i1 %b1, ptr %mStackData, ptr @g6
  %i3 = tail call noalias ptr @_Znam(i64 48) #3
  %i4 = tail call noalias ptr @_Znam(i64 48) #3
  %.v = select i1 %b2, ptr %i3, ptr %i4
  %i6 = icmp eq ptr %.v, %i2
  br i1 %i6, label %bb8, label %bb7

bb7:                                              ; preds = %bb
  call void @_ZdaPv(ptr %i3) #4
  call void @_ZdaPv(ptr %i4) #4
  br label %bb8

bb8:                                              ; preds = %bb7, %bb
  ret void
}

define void @_Z2p2v(i32 %c) {
; CHECK-LABEL: @_Z2p2v(
; CHECK-NEXT:  bb:
; CHECK-NEXT:    [[MSTACKDATA:%.*]] = alloca [10 x i32], i32 [[C:%.*]], align 16
; CHECK-NEXT:    [[I1:%.*]] = tail call noalias ptr @_Znam(i64 48) #[[ATTR2]]
; CHECK-NEXT:    [[I4:%.*]] = icmp eq ptr [[I1]], [[MSTACKDATA]]
; CHECK-NEXT:    br i1 [[I4]], label [[BB6:%.*]], label [[BB5:%.*]]
; CHECK:       bb5:
; CHECK-NEXT:    call void @_ZdaPv(ptr [[I1]]) #[[ATTR3]]
; CHECK-NEXT:    br label [[BB6]]
; CHECK:       bb6:
; CHECK-NEXT:    ret void
;
bb:
  %mStackData = alloca [10 x i32], i32 %c, align 16
  %i1 = tail call noalias ptr @_Znam(i64 48) #3
  %i4 = icmp eq ptr %i1, %mStackData
  br i1 %i4, label %bb6, label %bb5

bb5:                                              ; preds = %bb
  call void @_ZdaPv(ptr %i1) #4
  br label %bb6

bb6:                                              ; preds = %bb5, %bb
  ret void
}

; Function Attrs: nobuiltin
declare noalias ptr @_Znam(i64) #1

; Function Attrs: nobuiltin nounwind
declare void @_ZdaPv(ptr) #2

attributes #1 = { nobuiltin }
attributes #2 = { nobuiltin nounwind }
attributes #3 = { builtin }
attributes #4 = { builtin nounwind }
